﻿//JumbotCms_4.1 Final
using System;
using System.Data;
using System.Text;
using System.Xml;
using System.Web;
using System.Web.UI;
using Jumbot.Common;
using Jumbot.DataOper;
using JumbotCms.DataObject;
namespace JumbotCms.API
{
    /// <summary>
    /// 生成html主文件
    /// </summary>
    public class TemplateEngine : JumbotCms.Common.BasicPage
    {
        override protected void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }
        private string _PageTitle, _PageKeywords, _PageDescription, _PageNav, _DefaultSkinId;
        //当前频道信息
        public Channel Channel;
        //临时频道信息
        private Channel _Channel;
        private bool m_isHtml;
        /// <summary>
        /// 页面默认标题
        /// </summary>
        public string PageTitle
        {
            get { return this._PageTitle; }
            set { this._PageTitle = value; }
        }
        /// <summary>
        /// 页面默认关键字
        /// </summary>
        public string PageKeywords
        {
            get { return this._PageKeywords; }
            set { this._PageKeywords = value; }
        }
        /// <summary>
        /// 页面默认简介
        /// </summary>
        public string PageDescription
        {
            get { return this._PageDescription; }
            set { this._PageDescription = value; }
        }
        /// <summary>
        /// 页面链接导航
        /// </summary>
        public string PageNav
        {
            get { return this._PageNav; }
            set { this._PageNav = value; }
        }
        /// <summary>
        /// 默认皮肤ID
        /// </summary>
        public string DefaultSkinId
        {
            get { return this._DefaultSkinId; }
            set { this._DefaultSkinId = value; }
        }
        /// <summary>
        /// 是否缓存页面
        /// </summary>
        public bool IsHtml
        {
            get { return this.m_isHtml; }
            set { this.m_isHtml = value; }
        }
        public TemplateEngine()
        {
        }
        public TemplateEngine(DbOperHandler Doh, string _ChannelId)
        {
            doh = Doh;
            site = (Site)System.Web.HttpContext.Current.Application["System:Info"];
            Channel = new Channel();
            if (_ChannelId == string.Empty || _ChannelId == "0")
                Channel.GetAllColumn("0", doh);
            else
                Channel.GetAllColumn(_ChannelId, doh);
            DefaultSkinId = Jumbot.Common.XmlCOM.ReadConfig("~/_data/config/skin", "DefaultId");
            //_Channel = Channel;

        }
        /// <summary>
        /// 判断最终页面是否缓存
        /// </summary>
        /// <returns></returns>
        public bool PageIsHtml()
        {
            if (Channel.Id == "0")//没指定频道
                return (site.IsHtml);
            else
                return (site.IsHtml && Channel.IsHtml);
        }
        private string p__getNeightor(bool isHtml, string ccType, string ccId, string ClassId, string ViewId)
        {
            StringBuilder sb = new StringBuilder();
            doh.Reset();
            doh.SqlCmd = "SELECT TOP 1 [Id],[Title],[AddDate] FROM [jcms_module_" + ccType + "] WHERE [ChannelId] = " + ccId + " And [IsPass]=1 AND [Id]<" + ViewId + " order By [Id] DESC";
            DataTable dtContent = doh.GetDataTable();
            if (dtContent.Rows.Count > 0)
                sb.Append("<div class=\"l\"><span title=\"往前\">&laquo;</span> <a title=\"" + dtContent.Rows[0]["Title"].ToString() + "\" href=\"" + Go2View(doh, 1, isHtml, ccId, dtContent.Rows[0]["Id"].ToString()) + "\">" + dtContent.Rows[0]["Title"].ToString() + "</a></div>\r\n");
            doh.Reset();
            doh.SqlCmd = "SELECT TOP 1 [Id],[Title],[AddDate],[OutUrl] FROM [jcms_module_" + ccType + "] WHERE [ChannelId] = " + ccId + " AND [IsPass]=1 AND [Id]>" + ViewId + " order By [Id] ASC";
            dtContent = doh.GetDataTable();
            if (dtContent.Rows.Count > 0)
                sb.Append("<div class=\"r\"><span title=\"往后\">&raquo;</span> <a title=\"" + dtContent.Rows[0]["Title"].ToString() + "\" href=\"" + Go2View(doh, 1, isHtml, ccId, dtContent.Rows[0]["Id"].ToString()) + "\">" + dtContent.Rows[0]["Title"].ToString() + "</a></div>\r\n");
            dtContent.Clear();
            dtContent.Dispose();
            return sb.ToString();

        }

        /// <summary>
        /// 获得列表html
        /// </summary>
        /// <param name="ContentList"></param>
        /// <param name="ClassId"></param>
        /// <param name="ClassCode"></param>
        /// <param name="pSize"></param>
        /// <param name="pageCount"></param>
        /// <param name="page"></param>
        public void GetListBody(ref System.Collections.ArrayList ContentList, string ClassId, string ClassCode, string pSize, int pageCount, int page)
        {
            string whereStr = string.Empty;
            string PageStr = ContentList[0].ToString();
            whereStr = " [ClassID] in (SELECT ID FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Code] LIKE '" + ClassCode + "%')";
            whereStr += " AND [IsPass]=1";
            if (Channel.Id != "0")
                whereStr += " AND [ChannelId]=" + Channel.Id;
            int PSize = Convert.ToInt32(pSize);
            if (PSize < 1) PSize = 20;

            System.Collections.ArrayList TagArray = Jumbot.Common.Strings.GetHtmls(PageStr, "{$jcms:class(", "{$/jcms:class}", false, false);
            if (TagArray.Count > 0)//标签存在
            {
                string LoopBody = string.Empty;
                string TempStr = string.Empty;
                string FiledsStr = string.Empty;
                int StartTag, EndTag;

                StartTag = TagArray[0].ToString().IndexOf(")}", 0);
                FiledsStr = TagArray[0].ToString().Substring(0, StartTag);
                EndTag = TagArray[0].ToString().Length;
                LoopBody = "{$jcms:class(" + TagArray[0].ToString() + "{$/jcms:class}";
                TempStr = TagArray[0].ToString().Substring(StartTag + 2, EndTag - StartTag - 2);//需要循环的部分
                ContentList.Add(LoopBody);

                if (pageCount > 0)
                {
                    if (page == 0)
                    {
                        for (int i = 1; i < pageCount + 1; i++)
                        {
                            string wStr = Jumbot.Common.staticFunction.GetSql("Id,ChannelId,ClassId,[OutUrl]," + FiledsStr, "jcms_module_" + Channel.Type, "id", PSize, i, "desc", whereStr);
                            doh.Reset();
                            doh.SqlCmd = wStr;
                            DataTable dtContent = doh.GetDataTable();
                            ContentList.Add(operateContentTag(dtContent, Channel.Type, 100, 200, "yyyy-MM-dd", TempStr));
                            dtContent.Clear();
                            dtContent.Dispose();

                        }
                    }
                    else
                    {
                        page = page == 0 ? 1 : page;
                        string wStr = Jumbot.Common.staticFunction.GetSql("Id,ChannelId,ClassId,[OutUrl]," + FiledsStr, "jcms_module_" + Channel.Type, "id", PSize, page, "desc", whereStr);
                        doh.Reset();
                        doh.SqlCmd = wStr;
                        DataTable dtContent = doh.GetDataTable();
                        ContentList.Add(operateContentTag(dtContent, Channel.Type, 100, 200, "yy-MM-dd", TempStr));
                        dtContent.Clear();
                        dtContent.Dispose();
                    }
                }
                else
                    ContentList.Add("  ");
            }
        }
        /// <summary>
        /// 替换专题标签
        /// </summary>
        /// <param name="PageStr"></param>
        public void ReplaceSpecialTag(ref string PageStr, string _SpecialId)
        {
            executeTag_Special(ref PageStr, _SpecialId);
        }
        /// <summary>
        /// 替换频道标签
        /// </summary>
        /// <param name="PageStr"></param>
        public void ReplaceChannelTag(ref string PageStr, string _ChannelId)
        {
            p__getChannelLoop(ref PageStr);//顺序不要颠倒
            executeTag_Channel(ref PageStr, _ChannelId);
        }
        private void p__getChannelLoop(ref string PageStr)
        {
            System.Collections.ArrayList TagArray = Jumbot.Common.Strings.GetHtmls(PageStr, "{$ListLoop(", "{$/ListLoop}", false, false);
            if (TagArray.Count > 0)//标签存在
            {
                string LoopBody = string.Empty;
                string TempStr = string.Empty;
                string ViewStr = string.Empty;
                string ReplaceStr = string.Empty;
                string[] ParameterArray;
                int StartTag, EndTag;
                for (int i = 0; i < TagArray.Count; i++)
                {
                    StartTag = TagArray[i].ToString().IndexOf(")}", 0);
                    ReplaceStr = TagArray[i].ToString().Substring(0, StartTag);
                    ParameterArray = ReplaceStr.Split(',');
                    EndTag = TagArray[i].ToString().Length;
                    LoopBody = "{$ListLoop(" + TagArray[i].ToString() + "{$/ListLoop}";
                    TempStr = TagArray[i].ToString().Substring(StartTag + 2, EndTag - StartTag - 2);//需要循环的部分
                    string pStr = " [Id],[Title],[Info],[TopicNum],[Code],[ChannelId] FROM [jcms_normal_class] WHERE [IsOut]=0 AND [IsTop]=1 AND [ChannelId]=" + Channel.Id;
                    string oStr = " ORDER BY code";
                    doh.Reset();
                    if (ParameterArray.Length == 2)
                    {
                        if (ParameterArray[0] != "-1" && ParameterArray[0] != "0")
                            pStr += " AND Len(Code)=" + (Convert.ToInt32(ParameterArray[0]) * 4);
                        if (ParameterArray[1] != "0")
                            pStr = " top " + ParameterArray[1] + pStr;
                    }
                    else
                    {
                        ParameterArray[2] = ParameterArray[2].Replace('|', ',');
                        pStr += " AND [id] in " + ParameterArray[2];
                    }
                    doh.SqlCmd = "select" + pStr + oStr;
                    //PageStr =doh.SqlCmd;
                    DataTable dtClass = doh.GetDataTable();
                    StringBuilder sb = new StringBuilder();
                    for (int j = 0; j < dtClass.Rows.Count; j++)
                    {
                        if (ParameterArray[0] == "-1")
                        {
                            doh.Reset();
                            //doh.SqlCmd = "SELECT count(id) AS CC FROM [jcms_normal_class] WHERE [IsOut]=0 AND [ChannelId]=" + Channel.Id + " AND [code] LIKE '" + dtClass.Rows[j]["Code"].ToString() + "%'";
                            doh.ConditionExpress = "[IsOut]=0 AND [ChannelId]=" + Channel.Id + " AND [code] LIKE '" + dtClass.Rows[j]["Code"].ToString() + "%'";
                            int countNum = doh.Count("jcms_normal_class");
                            if (countNum > 1)
                                continue;
                        }
                        ViewStr = TempStr;
                        executeTag_Class(ref ViewStr, dtClass.Rows[j]["Id"].ToString());
                        sb.Append(ViewStr);
                    }
                    PageStr = PageStr.Replace(LoopBody, sb.ToString());
                    dtClass.Clear();
                    dtClass.Dispose();
                }
            }
        }
        /// <summary>
        /// 判断内容阅读权限
        /// 假设内容ID和栏目ID都已经正确
        /// </summary>
        /// <param name="_ContentId"></param>
        /// <param name="_ClassId"></param>
        /// <returns></returns>
        public bool CanReadContent(string _ContentId, string _ClassId)
        {
            if (Cookie.GetValue(site.CookiePrev + "admin") != null)//管理员直接可以看
                return true;
            int _UserGroup = 0;
            if (Cookie.GetValue(site.CookiePrev + "user") != null)
                _UserGroup = Str2Int(Cookie.GetValue(site.CookiePrev + "user", "groupid"));
            doh.Reset();
            doh.ConditionExpress = "id=" + _ContentId;
            int _ContentReadGroup = Str2Int(doh.GetValue("jcms_module_" + Channel.Type, "ReadGroup").ToString());
            if (_ContentReadGroup > -1)//说明不是继承栏目
            {
                if (_ContentReadGroup > _UserGroup)
                    return false;
                else
                    return true;
            }
            else
            {
                doh.Reset();
                doh.ConditionExpress = "id=" + _ClassId;
                int _ClassReadGroup = Str2Int(doh.GetValue("jcms_normal_class", "ReadGroup").ToString());
                if (_ClassReadGroup > _UserGroup)
                    return false;
                else
                    return true;

            }
        }
        /// <summary>
        /// 替换栏目标签
        /// </summary>
        /// <param name="PageStr"></param>
        public void ReplaceClassTag(ref string PageStr, string _ClassId)
        {
            executeTag_Class(ref PageStr, _ClassId);
        }
        /// <summary>
        /// 替换单页内容标签
        /// </summary>
        /// <param name="PageStr"></param>
        public void ReplaceContentTag(ref string PageStr, string _ContentId)
        {
            executeTag_Content(ref PageStr, _ContentId);
        }
        /// <summary>
        /// 解析循环标签
        /// </summary>
        /// <param name="PageStr">原始内容</param>
        /// <returns></returns>
        public void ReplaceRepeatTag(ref string PageStr)
        {
            replaceTag_RepeatLi(ref PageStr);
        }
        /// <summary>
        /// 解析站点信息
        /// </summary>
        /// <param name="PageStr">原始内容</param>
        /// <returns></returns>
        public void ReplaceSiteTags(ref string PageStr)
        {
            replaceTag_SiteConfig(ref PageStr);
            replaceTag_SkinAll(ref PageStr, DefaultSkinId);
        }
        /// <summary>
        /// 解析公共标签
        /// </summary>
        /// <param name="PageStr">原始内容</param>
        /// <param name="pId">模板组ID</param>
        /// <param name="skinId">皮肤ID</param>
        /// <returns></returns>
        public void ReplacePublicTag(ref string PageStr, string pId, string skinId)
        {
            if (pId != "0") replaceTag_My(ref PageStr, pId);
            replaceTag_SiteConfig(ref PageStr);
            replaceTag_Include(ref PageStr);
            replaceTag_SkinPath(ref PageStr, skinId);
            replaceTag_ChannelList(ref PageStr);
        }
        /// <summary>
        /// 解析javascript调用参数
        /// <para>ParameterArray[0]：频道id</para> 
        /// <para>ParameterArray[1]：栏目id, 0=上面指定频道的所有栏目</para> 
        /// <para>ParameterArray[2]：记录数</para> 
        /// <para>ParameterArray[3]：类型(可选参数)默认为simple</para> 
        /// <para>ParameterArray[4]：标题长度(可选参数)</para> 
        /// </summary>
        /// <param name="PageStr"></param>
        /// <param name="ParameterArray"></param>
        public string ReplaceJavascriptTag(string[] ParameterArray)
        {
            return getContentList_RL(ParameterArray);
        }
        /// <summary>
        /// 替换html包含标签
        /// </summary>
        /// <param name="PageStr"></param>
        private void replaceTag_Include(ref string PageStr)
        {
            System.Collections.ArrayList TagArray = Jumbot.Common.Strings.GetHtmls(PageStr, "{$jcms:include(", ")$/}", false, false);
            if (TagArray.Count > 0)//标签存在
            {
                string LoopBody = string.Empty;
                string FilePath = string.Empty;
                string ReplaceStr = string.Empty;
                for (int i = 0; i < TagArray.Count; i++)
                {
                    FilePath = TagArray[i].ToString();
                    if (!FilePath.StartsWith("/"))
                        FilePath = site.Dir + "_data/html/" + FilePath;
                    LoopBody = "{$jcms:include(" + TagArray[i].ToString() + ")$/}";
                    if (PageIsHtml() && site.StaticExt == ".aspx")
                        ReplaceStr = "<!--#include virtual=\"" + TagArray[i].ToString() + "\" -->";
                    else
                    {
                        if (Jumbot.Common.DirFile.FileExists(FilePath))
                            ReplaceStr = Jumbot.Common.DirFile.ReadFile(FilePath);
                        else
                            ReplaceStr = "";
                    }
                    PageStr = PageStr.Replace(LoopBody, ReplaceStr);
                }
            }
        }
        /// <summary>
        /// 替换片段代码块
        /// </summary>
        /// <param name="PageStr">已取到的模板内容</param>
        /// <param name="pid">模板项目id</param>
        private void replaceTag_My(ref string PageStr, string pId)
        {
            //if (PageStr.IndexOf("{$jcms:my.") > -1)
            if (PageStr.Contains("{$jcms:my."))
            {
                doh.Reset();
                doh.SqlCmd = "SELECT [Title],[source] FROM [jcms_normal_templatelabel] WHERE [pid]=" + pId + " ORDER BY sort desc";
                DataTable dtTempLabel = doh.GetDataTable();
                for (int i = 0; i < dtTempLabel.Rows.Count; i++)
                {
                    PageStr = PageStr.Replace("{$jcms:my." + dtTempLabel.Rows[i]["Title"].ToString() + "}", Jumbot.Common.DirFile.ReadFile(site.Dir + dtTempLabel.Rows[i]["source"].ToString()));

                }
                dtTempLabel.Clear();
                dtTempLabel.Dispose();
            }
        }
        /// <summary>
        /// 替换皮肤路径标签
        /// </summary>
        /// <param name="PageStr">已取到的模板内容</param>
        /// <param name="_SkinId">皮肤id</param>
        private void replaceTag_SkinPath(ref string PageStr, string _SkinId)
        {
            doh.Reset();
            doh.SqlCmd = "SELECT TOP 1 [source] FROM [jcms_normal_skins] WHERE [id]=" + _SkinId;
            DataTable dtSkin = doh.GetDataTable();
            if (dtSkin.Rows.Count != 1)
            {
                doh.Reset();
                doh.SqlCmd = "SELECT TOP 1 [source] FROM [jcms_normal_skins] ORDER BY Id";
                dtSkin = doh.GetDataTable();
            }
            PageStr = PageStr.Replace("{$SkinPath}", dtSkin.Rows[0]["source"].ToString());
            dtSkin.Clear();
            dtSkin.Dispose();
        }
        /// <summary>
        /// 替换皮肤所有标签
        /// </summary>
        /// <param name="PageStr">已取到的模板内容</param>
        /// <param name="_SkinId">皮肤id</param>
        private void replaceTag_SkinAll(ref string PageStr, string _SkinId)
        {
            JumbotCms.API.PageCSSManage pcm = new JumbotCms.API.PageCSSManage();
            doh.Reset();
            doh.SqlCmd = "SELECT TOP 1 [ID],[Title],[Source],[BodyWidth],[LeftWidth],[RightWidth],[TitleColor],[BorderColor],[TintBackground],[DarkBackground] FROM [jcms_normal_skins] WHERE [Id]=" + _SkinId;
            DataTable dtSkin = doh.GetDataTable();
            if (dtSkin.Rows.Count != 1)
            {
                doh.Reset();
                doh.SqlCmd = "SELECT TOP 1 [ID],[Title],[Source],[BodyWidth],[LeftWidth],[RightWidth],[TitleColor],[BorderColor],[TintBackground],[DarkBackground] FROM [jcms_normal_skins] ORDER BY Id";
                dtSkin = doh.GetDataTable();
            }
            pcm.Path = dtSkin.Rows[0]["Source"].ToString();
            pcm.BodyWidth = Str2Int(dtSkin.Rows[0]["BodyWidth"].ToString());
            pcm.LeftWidth = Str2Int(dtSkin.Rows[0]["LeftWidth"].ToString());
            pcm.RightWidth = Str2Int(dtSkin.Rows[0]["RightWidth"].ToString());
            pcm.TitleColor = dtSkin.Rows[0]["TitleColor"].ToString();
            pcm.BorderColor = dtSkin.Rows[0]["BorderColor"].ToString();
            pcm.TintBackground = dtSkin.Rows[0]["TintBackground"].ToString();
            pcm.DarkBackground = dtSkin.Rows[0]["DarkBackground"].ToString();
            pcm.Oper(ref PageStr);
            dtSkin.Clear();
            dtSkin.Dispose();
        }
        /// <summary>
        /// 替换丢弃代码标签
        /// </summary>
        /// <param name="PageStr">已取到的模板内容</param>
        private void replaceTag_NoShow(ref string PageStr)
        {
            System.Collections.ArrayList TagArray = Jumbot.Common.Strings.GetHtmls(PageStr, "<!--~", "~-->", false, false);
            if (TagArray.Count > 0)//标签存在
            {
                string TempStr = string.Empty;
                string ReplaceStr;
                for (int i = 0; i < TagArray.Count; i++)
                {
                    TempStr = "<!--~" + TagArray[i].ToString() + "~-->";
                    ReplaceStr = "";
                    PageStr = PageStr.Replace(TempStr, ReplaceStr);
                }
            }
        }
        /// <summary>
        /// 替换公共标签
        /// </summary>
        /// <param name="PageStr"></param>
        private void replaceTag_SiteConfig(ref string PageStr)
        {
            PageStr = PageStr.Replace("{site.Description}", site.Description);
            PageStr = PageStr.Replace("{site.Keywords}", site.Keywords);
            PageStr = PageStr.Replace("{site.Author}", "jumbot,随风缘");
            PageStr = PageStr.Replace("{site.Url}", site.Url);
            PageStr = PageStr.Replace("{site.Dir}", site.Dir);
            PageStr = PageStr.Replace("{site.Name}", site.Name);
            PageStr = PageStr.Replace("{site.UserItem}", site.UserItem);
            PageStr = PageStr.Replace("{site.WriterItem}", site.WriterItem);
            PageStr = PageStr.Replace("{site.ForumUrl}", site.ForumUrl);
            PageStr = PageStr.Replace("{site.LoginUrl}", site.LoginUrl);
            PageStr = PageStr.Replace("{site.LogoutUrl}", site.LogoutUrl);
            PageStr = PageStr.Replace("{site.RegisterUrl}", site.RegisterUrl);
            PageStr = PageStr.Replace("{site.GetPasswordUrl}", site.GetPasswordUrl);
            if (Channel.Id != "0")
                PageStr = PageStr.Replace("{$jcms:site.page.basehref}", site.Url + site.Dir + Channel.Dir + "/");
            else
                PageStr = PageStr.Replace("{$jcms:site.page.basehref}", site.Url + site.Dir);
            PageStr = PageStr.Replace("{$jcms:site.page.nav}", this._PageNav);
            PageStr = PageStr.Replace("{$jcms:site.page.title}", this._PageTitle);
            PageStr = PageStr.Replace("{$jcms:site.page.keywords}", this._PageKeywords);
            PageStr = PageStr.Replace("{$jcms:site.page.description}", this._PageDescription);
            replaceTag_NoShow(ref PageStr);
        }
        /// <summary>
        /// 版权信息
        /// </summary>
        private string GetCopyright()
        {
            return "<div id=\"ajaxCopyright\">Powered by JumbotCms &copy;2009. </div>\r\n<script>ajaxCopyright(\"ajaxCopyright\");</script>";
        }
        /// <summary>
        /// 替换频道循环标签
        /// </summary>
        /// <param name="PageStr"></param>
        private void replaceTag_ChannelList(ref string PageStr)
        {
            System.Collections.ArrayList TagArray = Jumbot.Common.Strings.GetHtmls(PageStr, "{$jcms:channel(", "{$/jcms:channel}", false, false);
            if (TagArray.Count > 0)//标签存在
            {
                string LoopBody = string.Empty;
                string TempStr = string.Empty;
                string ViewStr = string.Empty;
                string ReplaceStr = string.Empty;
                string[] ParameterArray;
                int StartTag, EndTag;
                for (int i = 0; i < TagArray.Count; i++)
                {
                    StartTag = TagArray[i].ToString().IndexOf(")}", 0);
                    ReplaceStr = TagArray[i].ToString().Substring(0, StartTag);
                    ParameterArray = ReplaceStr.Split(',');
                    EndTag = TagArray[i].ToString().Length;
                    LoopBody = "{$jcms:channel(" + TagArray[i].ToString() + "{$/jcms:channel}";
                    TempStr = TagArray[i].ToString().Substring(StartTag + 2, EndTag - StartTag - 2);//需要循环的部分
                    doh.Reset();
                    if (ParameterArray.Length == 1)
                        doh.SqlCmd = "select top " + ParameterArray[0] + " [Id],[Title] FROM [jcms_normal_channel] WHERE [IsOut]<1 AND [Enabled]=1 ORDER BY pId Asc";
                    else
                        doh.SqlCmd = "select top " + ParameterArray[0] + " [Id],[Title] FROM [jcms_normal_channel] WHERE [IsOut]<1 AND [Enabled]=1 AND id in " + ParameterArray[1].Replace("|", ",").Replace("\'", ",") + " ORDER BY pId Asc";
                    DataTable dtChannel = doh.GetDataTable();
                    StringBuilder sb = new StringBuilder();
                    for (int j = 0; j < dtChannel.Rows.Count; j++)
                    {
                        ViewStr = TempStr;
                        ViewStr = ViewStr.Replace("{$ChannelId}", dtChannel.Rows[j]["Id"].ToString());
                        ViewStr = ViewStr.Replace("{$ChannelName}", dtChannel.Rows[j]["Title"].ToString());
                        sb.Append(ViewStr);
                    }
                    PageStr = PageStr.Replace(LoopBody, sb.ToString());
                    dtChannel.Clear();
                    dtChannel.Dispose();
                }
            }
        }
        /// <summary>
        /// 替换循环标签
        /// </summary>
        /// <param name="PageStr"></param>
        private void replaceTag_RepeatLi(ref string PageStr)
        {
            System.Collections.ArrayList TagArray = Jumbot.Common.Strings.GetHtmls(PageStr, "{$jcms:content(", ")$/}", false, false);
            if (TagArray.Count > 0)//标签存在
            {
                string LoopBody = string.Empty;
                string TempStr = string.Empty;
                string ViewStr = string.Empty;
                string ReplaceStr = string.Empty;
                string[] ParameterArray;
                for (int i = 0; i < TagArray.Count; i++)
                {
                    ParameterArray = TagArray[i].ToString().Split(',');
                    LoopBody = "{$jcms:content(" + TagArray[i].ToString() + ")$/}";
                    ReplaceStr = getContentList_RL(ParameterArray);
                    PageStr = PageStr.Replace(LoopBody, ReplaceStr);
                }
            }
        }
        /// <summary>
        /// 提取列表供列表标签使用，形如(0,0,8,simple)
        /// <para>参数0：频道id，如在频道中使用，设为{$ChannelId}即可,如果为0默认为第一个频道</para>
        /// <para>参数1：栏目id, 0=上面指定频道的所有栏目,如在栏目中使用,设为{$ClassId}即可</para>
        /// <para>参数2：记录数</para>
        /// <para>参数3：类型(可选参数)默认为simple</para>
        /// <para>参数4：标题最大长度(可选参数),优先权大于宏标记中的参数值</para>
        /// </summary>
        /// <param name="Parameter"></param>

        /// <returns></returns>
        private string getContentList_RL(string[] Parameter)
        {
            string _ccId = string.Empty;
            string _ccType = string.Empty;
            for (int i = 0; i < 3; i++)
            {
                if (!Jumbot.Common.Validator.IsNumeric(Parameter[i]))
                    return "&nbsp;参数有误";
            }
            if (Str2Str(Parameter[0]) != "0")
            {
                doh.Reset();
                doh.SqlCmd = "SELECT [Id],[Type] FROM [jcms_normal_channel] WHERE [Id]=" + Parameter[0] + " AND [IsOut]<1 AND [Enabled]=1";
                DataTable dtChannel = doh.GetDataTable();
                if (dtChannel.Rows.Count > 0)
                {
                    _ccId = dtChannel.Rows[0]["Id"].ToString();
                    _ccType = dtChannel.Rows[0]["Type"].ToString();
                }
                else
                    return "&nbsp;频道参数" + Str2Str(Parameter[0]) + "错误";
                dtChannel.Clear();
                dtChannel.Dispose();
            }
            else
            {
                _ccId = "0";
                doh.Reset();
                doh.SqlCmd = "SELECT TOP 1 [Type] FROM [jcms_normal_modules] WHERE [Enabled]=1";
                DataTable dtModule = doh.GetDataTable();
                if (dtModule.Rows.Count > 0)
                {
                    _ccType = dtModule.Rows[0]["Type"].ToString();
                }
                else
                {
                    return "&nbsp;频道参数错误";
                }
                dtModule.Clear();
                dtModule.Dispose();
            }
            string repeatCode = "simple";
            string strXmlFile = HttpContext.Current.Server.MapPath("~/_data/config/jcms(contentli).config");
            Jumbot.DataOper.XmlControl XmlTool = new Jumbot.DataOper.XmlControl(strXmlFile);
            if (Parameter.Length > 3)
            {
                repeatCode = Parameter[3];
                string _CodeId = XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/ID");
                if (_CodeId == "")
                    repeatCode = "simple";
            }
            string _Fields = XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/Fields");
            string _OrderBy = XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/OrderBy").ToLower();
            int _IsTop = Str2Int(XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/IsTop"), 0);
            int _IsImg = Str2Int(XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/IsImg"), 0);
            int _TitleLen = Str2Int(XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/TitleLen"), 20);
            //优先定义标题长度
            if (Parameter.Length > 4)
                _TitleLen = Str2Int(Parameter[4]) > 0 ? Str2Int(Parameter[4]) : _TitleLen;
            int _SummaryLen = Str2Int(XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/SummaryLen"), 50);
            string _DateFormat = XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/DateFormat");
            string _Repeat = XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/Repeat");
            replaceTag_SiteConfig(ref _Repeat);
            string _Content = XmlTool.GetText("Lis/Li[Code=\"" + repeatCode + "\"]/Content");
            replaceTag_SiteConfig(ref _Content);
            XmlTool.Dispose();
            executeTag_Channel(ref _Content, _ccId);
            if (Parameter[1] != "0")
                executeTag_Class(ref _Content, Parameter[1]);

            string sql = "SELECT TOP " + Parameter[2] + " [Id],[ChannelId],[ClassId],[OutUrl]," + _Fields + " FROM [jcms_module_" + _ccType + "] WHERE ([IsPass]=1";
            if (_ccId != "0")
            {
                string isChannel = " AND [ChannelId]=" + _ccId;
                sql += isChannel;
                if (Parameter[1] != "0")
                    sql += " And [ClassID] in (SELECT ID FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Code] Like (SELECT Code FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Id]=" + Parameter[1].ToString() + isChannel + ")+'%')" + isChannel;
            }
            else
            {
                if (Parameter[1] != "0")
                    sql += " And [ClassID] in (SELECT ID FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Code] Like (SELECT Code FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Id]=" + Parameter[1].ToString() + ")+'%')";
                else
                    sql += " And [ChannelID] in (SELECT ID FROM [jcms_normal_channel] WHERE [IsOut]<1 AND [Type]='" + _ccType + "' AND [Enabled]=1)";

            }
            if (_IsTop == 1)
                sql += " And [IsTop]=1";
            if (_IsImg == 1)
                sql += " And [IsImg]=1 And (right(Img,4)='.jpg' Or right(Img,4)='.gif')";
            if (_OrderBy != "id")
                sql += ") ORDER BY " + _OrderBy + " Desc,id Desc";
            else
                sql += ") ORDER BY id Desc";
            doh.Reset();
            doh.SqlCmd = sql;
            DataTable dt = doh.GetDataTable();
            string ReplaceStr = operateContentTag(dt, _ccType, _TitleLen, _SummaryLen, _DateFormat, _Repeat);
            dt.Clear();
            dt.Dispose();
            return _Content.Replace("$Repeat$", ReplaceStr);
        }
        private string operateContentTag(DataTable dt, string ccType, int TitleLen, int SummaryLen, string DateFormat, string TempStr)
        {
            string randomStr = "1" + RandomStr(4);
            string ReplaceStr = string.Empty;
            StringBuilder sb = new StringBuilder("");
            if (dt.Rows.Count > 0)
            {
                for (int j = 0; j < dt.Rows.Count; j++)
                {
                    ReplaceStr = TempStr;
                    //以下是预处理
                    ReplaceStr = ReplaceStr.Replace("{$_no$}", (j + 1).ToString());
                    ReplaceStr = ReplaceStr.Replace("{$_url$}", Go2View(doh, 1, (dt.Rows[j]["OutUrl"].ToString() != ""), dt.Rows[j]["ChannelId"].ToString(), dt.Rows[j]["Id"].ToString()));
                    ReplaceStr = ReplaceStr.Replace("{$_title0$}", Jumbot.Common.Strings.HtmlEncode(dt.Rows[j]["Title"].ToString()));
                    //下面的标签少用为妙，因为会多占资源
                    ReplaceStr = ReplaceStr.Replace("{$_classurl$}", Go2Class(doh,1,false, dt.Rows[j]["ChannelId"].ToString(), dt.Rows[j]["ClassId"].ToString()));
                    ReplaceStr = ReplaceStr.Replace("{$_classname$}", (new JumbotCms.DataObject.Class().GetClassName(dt.Rows[j]["ClassId"].ToString(), doh)));


                    //以下是正规处理
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        switch (dt.Columns[i].ColumnName.ToLower())
                        {
                            case "title":
                                ReplaceStr = ReplaceStr.Replace("{$_title$}", Jumbot.Common.Strings.CutTitle(Jumbot.Common.Strings.HtmlEncode(dt.Rows[j]["Title"].ToString()), TitleLen));
                                break;
                            case "summary":
                                ReplaceStr = ReplaceStr.Replace("{$_summary$}", Jumbot.Common.Strings.CutTitle(Jumbot.Common.Strings.NoHTML(dt.Rows[j]["Summary"].ToString()), SummaryLen));
                                break;
                            case "adddate":
                                ReplaceStr = ReplaceStr.Replace("{$_adddate$}", Convert.ToDateTime(dt.Rows[j]["AddDate"]).ToString(DateFormat));
                                break;
                            case "viewnum":
                                ReplaceStr = ReplaceStr.Replace("{$_viewnum$}", "<span id=\"ajaxViewCount_" + dt.Rows[j]["Id"].ToString() + "_" + randomStr + "\"><img src=\"" + site.Dir + "style/loading.gif\" border=\"0\"><script>ajaxViewCount('" + ccType + "'," + dt.Rows[j]["Id"].ToString() + "," + randomStr + ",false)</script></span>");
                                break;
                            case "img":
                                if (dt.Rows[j]["IsImg"].ToString() == "0" || dt.Rows[j]["Img"].ToString().Length == 0)
                                    ReplaceStr = ReplaceStr.Replace("{$_img$}", site.Dir + "style/jumbotcms/nopic.gif");
                                else
                                    ReplaceStr = ReplaceStr.Replace("{$_img$}", dt.Rows[j]["Img"].ToString());
                                break;
                            default:
                                ReplaceStr = ReplaceStr.Replace("{$_" + dt.Columns[i].ColumnName.ToLower() + "$}", dt.Rows[j][i].ToString());
                                break;
                        }
                    }
                    sb.Append(ReplaceStr);
                }
            }
            return sb.ToString();
        }
        /// <summary>
        /// 解析专题标签
        /// </summary>
        /// <param name="PageStr"></param>
        /// <param name="_SpecialId">SpecialId不能为0</param>
        /// <returns></returns>
        private void executeTag_Special(ref string PageStr, string _SpecialId)
        {
            Special _Special = new Special();
            _Special.GetAllColumn(_SpecialId, doh);
            PageStr = PageStr.Replace("{$SpecialId}", _Special.Id);
            PageStr = PageStr.Replace("{$SpecialName}", _Special.Title);
            PageStr = PageStr.Replace("{$SpecialInfo}", _Special.Info);

        }
        /// <summary>
        /// 解析频道标签
        /// </summary>
        /// <param name="PageStr"></param>
        /// <param name="_ChannelId">ChannelId不能为0</param>
        /// <returns></returns>
        private void executeTag_Channel(ref string PageStr, string _ChannelId)
        {
            _Channel = new Channel();
            _Channel.GetAllColumn(_ChannelId, doh);
            PageStr = PageStr.Replace("{$ChannelId}", _Channel.Id);
            PageStr = PageStr.Replace("{$ChannelName}", _Channel.Title);
            PageStr = PageStr.Replace("{$ChannelInfo}", _Channel.Info);
            PageStr = PageStr.Replace("{$ChannelType}", _Channel.Type);
            PageStr = PageStr.Replace("{$ChannelDir}", _Channel.Dir);
            PageStr = PageStr.Replace("{$ChannelItemName}", _Channel.ItemName);
            PageStr = PageStr.Replace("{$ChannelItemUnit}", _Channel.ItemUnit);
            PageStr = PageStr.Replace("{$ChannelLink}", site.Dir + _Channel.Dir);

        }
        /// <summary>
        /// 解析栏目标签
        /// </summary>
        /// <param name="PageStr"></param>
        /// <param name="ClassId"></param>
        /// <returns></returns>
        private void executeTag_Class(ref string PageStr, string ClassId)
        {
            doh.Reset();
            doh.SqlCmd = "SELECT [Id],[Title],[Info],[TopicNum],[Code],[ChannelId] FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Id]=" + ClassId;
            DataTable dtClass = doh.GetDataTable();
            if (dtClass.Rows.Count > 0)
            {
                PageStr = PageStr.Replace("{$ClassId}", dtClass.Rows[0]["Id"].ToString());
                PageStr = PageStr.Replace("{$ClassName}", dtClass.Rows[0]["Title"].ToString());
                PageStr = PageStr.Replace("{$ClassInfo}", dtClass.Rows[0]["Info"].ToString());
                PageStr = PageStr.Replace("{$ClassTopicNum}", dtClass.Rows[0]["TopicNum"].ToString());
                PageStr = PageStr.Replace("{$ClassLink}", Go2Class(doh, 1, Channel.IsHtml, dtClass.Rows[0]["ChannelId"].ToString(), dtClass.Rows[0]["Id"].ToString()));
                PageStr = PageStr.Replace("{$ClassCode}", dtClass.Rows[0]["Code"].ToString());
            }
            dtClass.Clear();
            dtClass.Dispose();

        }
        /// <summary>
        /// 解析单条内容标签
        /// </summary>
        /// <param name="PageStr"></param>
        /// <param name="ContentId"></param>
        /// <returns></returns>
        private void executeTag_Content(ref string PageStr, string ContentId)
        {
            string randomStr = "1" + RandomStr(4);
            string TempStr = string.Empty;
            doh.Reset();
            doh.SqlCmd = "SELECT * FROM  [jcms_module_" + Channel.Type + "] WHERE [Id]=" + ContentId;
            DataTable dtContent = doh.GetDataTable();
            if (dtContent.Rows.Count > 0)
            {
                TempStr = p__getNeightor(Channel.IsHtml, Channel.Type, dtContent.Rows[0]["ChannelId"].ToString(), dtContent.Rows[0]["ClassId"].ToString(), ContentId);
                PageStr = PageStr.Replace("{$_getNeightor()}", TempStr);
                for (int i = 0; i < dtContent.Columns.Count; i++)
                {
                    if (dtContent.Rows[0]["IsImg"].ToString() == "0" || dtContent.Rows[0]["Img"].ToString().Length == 0)
                        PageStr = PageStr.Replace("{$_img}", site.Dir + "style/jumbotcms/nopic.gif");
                    else
                        PageStr = PageStr.Replace("{$_img}", dtContent.Rows[0]["Img"].ToString());
                    switch (dtContent.Columns[i].ColumnName.ToLower())
                    {
                        case "adddate":
                            PageStr = PageStr.Replace("{$_adddate}", Convert.ToDateTime(dtContent.Rows[0]["AddDate"]).ToString("yyyy-MM-dd"));
                            break;
                        case "viewnum":
                            PageStr = PageStr.Replace("{$_viewnum}", "<span id=\"ajaxViewCount_" + ContentId + "_" + randomStr + "\"><img src=\"" + site.Dir + "style/loading.gif\" border=\"0\"><script>ajaxViewCount('" + Channel.Type + "'," + ContentId + "," + randomStr + ")</script></span>");
                            break;
                        default:
                            PageStr = PageStr.Replace("{$_" + dtContent.Columns[i].ColumnName.ToLower() + "}", dtContent.Rows[0][i].ToString());
                            break;
                    }
                }
            }
            dtContent.Clear();
            dtContent.Dispose();
        }
        public string GetClassStr(string ClassId, int _currentPage)
        {
            doh.Reset();
            doh.SqlCmd = "SELECT * FROM [jcms_normal_class] WHERE [IsOut]=0 AND [ChannelId]=" + Channel.Id + " and [Id]=" + ClassId;
            DataTable dtClass = doh.GetDataTable();
            int countNum = 0;
            int PSize = Convert.ToInt32(dtClass.Rows[0]["PageSize"].ToString());
            string classCode = dtClass.Rows[0]["Code"].ToString();
            doh.Reset();
            string pStr = " [ClassID] in (Select id FROM [jcms_normal_class] WHERE [IsOut]=0 AND [Code] LIKE '" + classCode + "%') and [IsPass]=1 AND [ChannelId]=" + Channel.Id;
            doh.ConditionExpress = pStr;
            countNum = doh.Count("jcms_module_" + Channel.Type);
            int pageCount = Jumbot.Common.Int.PageCount(countNum, PSize);
            System.Collections.ArrayList ContentList = GetChannel_Class(dtClass, pageCount, _currentPage, 0);
            string ContentStr = ContentList[0].ToString();
            if (ContentList.Count > 2)
            {
                string ViewStr = ContentList[1].ToString();
                ContentStr = ContentStr.Replace(ViewStr, ContentList[2].ToString());
            }
            ContentStr = ContentStr.Replace("{$_getPageBar()}", getPageBar(3, "js", 2, countNum, PSize, _currentPage, Go2Class(doh, 1, Channel.IsHtml, Channel.Id, ClassId), Go2Class(doh, -1, Channel.IsHtml, Channel.Id, ClassId), Go2Class(doh, -1, false, Channel.Id, ClassId), site.CreatePages));
            dtClass.Clear();
            dtClass.Dispose();
            return ContentStr;
        }
        /// <summary>
        /// 生成栏目页(内容列表)
        /// </summary>
        /// <param name="ColumnRow"></param>
        /// <param name="pageCount"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        protected System.Collections.ArrayList GetChannel_Class(DataTable dt, int pageCount, int page, int i)
        {
            string ClassName = dt.Rows[i]["title"].ToString();
            string ClassId = dt.Rows[i]["id"].ToString();
            string pId = string.Empty;
            string sId = string.Empty;
            string PageStr = string.Empty;
            doh.Reset();
            doh.SqlCmd = "SELECT TOP 1 [pid],[Source],[SkinId] FROM [jcms_normal_template] WHERE [Id]=" + dt.Rows[i]["templateid"].ToString();
            DataTable dtTemplate = doh.GetDataTable();
            if (dtTemplate.Rows.Count > 0)
            {
                pId = dtTemplate.Rows[0]["pid"].ToString();
                sId = dtTemplate.Rows[0]["SkinId"].ToString();
                TemplateProject tp = new TemplateProject();
                PageStr = Jumbot.Common.DirFile.ReadFile(site.Dir + "templates/" + tp.GetDir(pId, doh) + "/" + dtTemplate.Rows[0]["Source"].ToString());
            }
            dtTemplate.Clear();
            dtTemplate.Dispose();
            PageNav = "<script type=\"text/javascript\" src=\"" + site.Dir + Channel.Dir + "/js/classnav_" + ClassId + ".js\"></script>&nbsp;&gt;&nbsp;列表";
            PageTitle = ClassName + "_" + Channel.Title + "_" + site.Name + site.TitleTail;
            PageKeywords = site.Keywords;
            PageDescription = Jumbot.Common.Strings.SimpleLineSummary(dt.Rows[i]["Info"].ToString());
            ReplacePublicTag(ref PageStr, pId, sId);
            ReplaceChannelTag(ref PageStr, dt.Rows[i]["ChannelId"].ToString());
            ReplaceClassTag(ref PageStr, ClassId);
            ReplaceRepeatTag(ref PageStr);
            System.Collections.ArrayList ContentList = new System.Collections.ArrayList();
            ContentList.Add(PageStr);
            GetListBody(ref ContentList, ClassId, dt.Rows[i]["code"].ToString(), dt.Rows[i]["pagesize"].ToString(), pageCount, page);

            return ContentList;
        }
    }
}